<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>原型对象</title>
    <script>
        /* 
            原型对象(prototype)
                访问一个对象的原型对象
                    1.对象.__proto___   这种方法不好，容易让原型混乱
                    2.Object.getPrototypeOf(要访问的对象))   (安全性高)
                    
            原型对象中的数据
                1.对象中的数据（比如属性，方法等）
                2. 对象中的构造函数 constructor   //也即是表示类是由那个对象创建的。

                对象有两个地方存储数据。一个是对象自身，一个是原型对象。
                
                注意：原型对象也是一个对象，原型对象中也有原型对象,这样就构成了一条原型链，根据对象的复杂程度不同，原型链的长度也不同。

                原型链：
                    在对象读取属性时，会顺着原型链寻找。
                        也就是也在对象本身中寻找，如果有，则使用，没有则去原型中寻找
                        原型中有，则使用，没有则取继续去原型的原型中寻找，直到Object对象的原型为null，最终没找到,则返回undefined

                
                作用域链是找变量，找不到就报错。原型链是找属性，找不到就报undefined！

        */
        class Person {
            constructor(a, b) {
                this.name = a;
                this.age = b;
            }
            //存储在原型对象中
            sayHello() {
                console.log(`hello,我是`, this.name)
            }


            sayHello1 = () => {
                console.log('我是箭头函数定义的方法', this.name)
            }
            sayHello2 = function () {
                console.log('我是通过函数定义创建的方法', this.name)
            }
        }

        const p1 = new Person('朱丽叶', 2)


        console.log(p1)
        console.log(p1.__proto__)   //访问原型对象
        console.log(Object.getPrototypeOf(p1))  // 静态方法，直接通过类直接调用，作用是检查某个地方的原型。
        console.log(Object.getPrototypeOf(p1)===p1.__proto__)       // true

        console.log(Object.getPrototypeOf(p1.__proto__))       // 访问原型对象中的原型对象
        console.log(p1.__proto__.__proto__.__proto__)     //p1-->原型对象(Person)-->原型对象的原型对象-->null

    </script>

</head>

<body>

</body>

</html>